package com.lcn.tm.service.transaction;

import com.lcn.comm.constant.Constants;
import com.lcn.comm.domain.CallbackInfo;
import com.lcn.comm.domain.TxGroup;
import com.lcn.comm.domain.TxGroupManager;
import com.lcn.comm.domain.TxRequest;
import com.lcn.comm.framework.netty.NettyClientManager;
import com.lcn.comm.service.redis.RedisService;
import com.lcn.comm.service.transaction.TransactionConfirmService;
import com.weibo.api.motan.rpc.DefaultRequest;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.transport.netty4.NettyClient;
import com.weibo.api.motan.util.LoggerUtil;
import com.weibo.api.motan.util.RequestIdGenerator;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <p>类说明</p>
 *
 * @author 张峰 zfvip_it@163.com
 * @create: 2017－12－23 上午10:07
 */
@Service
public class TransactionConfirmServiceImpl implements TransactionConfirmService {

    @Resource
    private RedisService redisService;

    private ExecutorService pool = Executors.newFixedThreadPool(10);

    /**
     * 事务组提交处理
     *
     * @param txGroup
     * @return
     */
    public int confirm(final TxGroup txGroup) {
        boolean flag = transaction(txGroup);
        if (flag) {
            //异步删除处理
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    //删除本地缓存
                    TxGroupManager.getInstance().removeGroup(txGroup.getGroupId());
                    //删除redis缓存
                    redisService.remove(txGroup.getGroupId());
                }
            });
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * 事务提交或回滚处理
     *
     * @param txGroup
     * @return
     */
    private boolean transaction(TxGroup txGroup) {
        List<TxRequest> list = txGroup.getList();
        TxRequest txRequest;
        NettyClient nettyClient;
        for (int i = 0, size = list.size(); i < size; i++) {
            txRequest = list.get(i);
            nettyClient = NettyClientManager.getInstance().getNettyClient(txRequest);
            try {
                nettyClient.request(getRequest(txRequest, txGroup.getState()));
                txRequest.setNotify(true);
            } catch (Exception e) {
                LoggerUtil.error(e.getMessage(), e);
                // TODO: 2017/12/28  记录到需要补偿的redis中
            }
        }
        redisService.setValue(txGroup.getGroupId(), txGroup);
        return true;
    }

    /**
     * 获取请求对象
     *
     * @param txRequest
     * @return
     */
    private Request getRequest(TxRequest txRequest, int checkState) {
        DefaultRequest request = new DefaultRequest();
        request.setRequestId(RequestIdGenerator.getRequestId());
        request.setInterfaceName(Constants.callBackInterfaceName);
        request.setMethodName(Constants.callBackMethodName);
        request.setParamtersDesc(Constants.callBackParamtersDesc);
        request.setArguments(new Object[]{getArguments(txRequest, checkState)});
        return request;
    }

    /**
     * 获取参数json对象
     *
     * @param txRequest
     * @param checkState
     * @return
     */
    private CallbackInfo getArguments(TxRequest txRequest, int checkState) {
        CallbackInfo callbackInfo = new CallbackInfo();
        callbackInfo.setGroupId(txRequest.getGroupId());
        callbackInfo.setRequestId(txRequest.getRequestId());
        callbackInfo.setState(checkState);
        return callbackInfo;
    }
}
